package com.luo.chengrui.framework.sadatapermission.core.aop;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.luo.chengrui.framework.sadatapermission.core.annotation.SaDataPermission;

import java.util.LinkedList;
import java.util.List;

/**
 * {@link SaDataPermission} 注解的 Context 上下文
 *
 * @author 芋道源码
 */
public class DataPermissionContextHolder {

    /**
     * 使用 List 的原因，可能存在方法的嵌套调用
     */
    private static final ThreadLocal<LinkedList<SaDataPermission>> DATA_PERMISSIONS =
            TransmittableThreadLocal.withInitial(LinkedList::new);


    private static final ThreadLocal<String> PERMISSION_CODE = new TransmittableThreadLocal<>();

    /**
     * 获得当前的 SaDataPermission 注解
     *
     * @return SaDataPermission 注解
     */
    public static SaDataPermission get() {
        return DATA_PERMISSIONS.get().peekLast();
    }

    /**
     * 入栈 SaDataPermission 注解
     *
     * @param SaDataPermission SaDataPermission 注解
     */
    public static void add(SaDataPermission SaDataPermission) {
        DATA_PERMISSIONS.get().addLast(SaDataPermission);
    }

    /**
     * 出栈 SaDataPermission 注解
     *
     * @return SaDataPermission 注解
     */
    public static SaDataPermission remove() {
        SaDataPermission SaDataPermission = DATA_PERMISSIONS.get().removeLast();
        // 无元素时，清空 ThreadLocal
        if (DATA_PERMISSIONS.get().isEmpty()) {
            DATA_PERMISSIONS.remove();
        }
        return SaDataPermission;
    }

    /**
     * 获得所有 SaDataPermission
     *
     * @return SaDataPermission 队列
     */
    public static List<SaDataPermission> getAll() {
        return DATA_PERMISSIONS.get();
    }

    /**
     * 清空上下文
     * <p>
     * 目前仅仅用于单测
     */
    public static void clear() {
        DATA_PERMISSIONS.remove();
    }

    public static void clearPermissionCode() {
        PERMISSION_CODE.remove();
    }

    public static void setPermissionCode(String permissionCode) {
        PERMISSION_CODE.set(permissionCode);
    }

    public static String getPermissionCode() {
        return PERMISSION_CODE.get();
    }


}
